package data;

import java.io.File;

import gene.GeneManager;

import java.io.IOException;

import util.Log;
import jxl.Cell;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.Number;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

public class Export {

	public WritableWorkbook workbook; // 워크북 생성

	public WritableSheet summary; // 제너레이션 마다 best Gene들의 cmax , fitness평균 피트니스
									// 에버리지 피트니스, 피트니스, 레퍼런스 피트니스
	public WritableSheet geneContent; // best gene의 gene의 형태
	public WritableSheet ltpSchedule; // best gene들의 스케줄링

	private static String filePath = System.getProperty("user.dir") + "/test";
	private final static String ext = ".xls";

	public void address() {

		try {
			this.getExel(filePath + ext);
		} catch (BiffException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void getExel(String address) throws BiffException, IOException {
		workbook = Workbook.createWorkbook(new File(address));

		summary = workbook.createSheet("summary", 1);
		geneContent = workbook.createSheet("geneContent", 2);
		ltpSchedule = workbook.createSheet("ltpSchedule", 3);
	}

	public void getExeltotal(String address) throws BiffException, IOException {
		workbook = Workbook.createWorkbook(new File(address));
	}

	public void export(GeneManager gm) {
		this.address();
		this.bestGeneExport(gm);
		this.geneContentExport(gm);
		this.scheduleExport(gm);

		try {
			workbook.write();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			workbook.close();
		} catch (WriteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void bestGeneExport(GeneManager gm) {

		int r = 1;

		for (int i = 0; i < gm.getBestGeneList().size(); i++) {
			// BestGeneList가져옴
			for (int j = 0; j < gm.getBestGeneList().get(i).scheduleList.size(); j++) {
				// gene에 해당하는 schedule 수
				String geneName = gm.getBestGeneList().get(i).getName();
				Label geneName1 = new Label(0, r, geneName);
				// Best Gene Name
				
				Number schedule = new Number(1, r, j);
				
				Number referenceCmax = new Number(2, r, gm.getBestGeneList().get(i).scheduleList.get(j).getRpListInSchedule().get(j).getReferenceCmax());
				// referenceCmax
				
				Number fitness = new Number(3, r, gm.getBestGeneList().get(i).scheduleList.get(j).getFitness());
				// cmax

				Number fitnessCompare = new Number(4, r, gm.getBestGeneList().get(i).scheduleList.get(j).getFitnessCompare());
				// referenceCmax - cmax

				Number averageFitness = new Number(5, r, gm.getBestGeneList().get(i).getAverageFiness());
				try {
					summary.addCell(geneName1);
					summary.addCell(schedule);
					summary.addCell(fitness);
					summary.addCell(referenceCmax);
					summary.addCell(fitnessCompare);
					summary.addCell(averageFitness);
				} catch (RowsExceededException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (WriteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				r++;
			}
			
		}
		Label GeneNme = new Label(0, 0, "GeneName");
		Label Schedule = new Label(1, 0, "Schedule");
		Label Fitness = new Label(2, 0, "Fitness");
		Label ReferenceCmax = new Label(3, 0, "ReferenceCmax");
		Label FitnessCompare = new Label(4, 0, "FitnessCompare");
		Label AverageFitness = new Label(5, 0, "AverageFitness");

		try {
			summary.addCell(GeneNme);
			summary.addCell(Schedule);
			summary.addCell(Fitness);
			summary.addCell(ReferenceCmax);
			summary.addCell(FitnessCompare);
			summary.addCell(AverageFitness);
		} catch (RowsExceededException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (WriteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void geneContentExport(GeneManager gm) {

		int a = 1;

		for (int i = 0; i < gm.getBestGeneList().size(); i++) {

			int b = 0;
			Label geneNumber = new Label(b++, a, gm.getBestGeneList().get(i).getName());
			Number nodeMaxDepth = new Number(b++, a, gm.getBestGeneList().get(i).getMaxHeight());

			String nameRoot = gm.getBestGeneList().get(i).getRootNode().getName();
			Label nodeRoot = new Label(b, a, nameRoot);
			b++;

			if (gm.getBestGeneList().get(i).getRootNode().getBranches() != null) {
				for (int j = 0; j < gm.getBestGeneList().get(i).getRootNode().getArity(); j++) {
					String nameFirst = gm.getBestGeneList().get(i).getRootNode().getChild(j).getName();
					Label nodeFirst = new Label(b, a, nameFirst);
					try {
						geneContent.addCell(nodeFirst);
					} catch (RowsExceededException e) {
						// TODO Auto-generated
						// catch block
						e.printStackTrace();
					} catch (WriteException e) {
						// TODO Auto-generated
						// catch block
						e.printStackTrace();
					}
					b++;

					if (gm.getBestGeneList().get(i).getRootNode().getChild(j).getBranches() != null) {
						for (int k = 0; k < gm.getBestGeneList().get(i).getRootNode().getChild(j).getArity(); k++) {
							String nameSecond = gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getName();
							Label nodeSecond = new Label(b, a, nameSecond);
							try {
								geneContent.addCell(nodeSecond);
							} catch (RowsExceededException e) {
								// TODO Auto-generated
								// catch block
								e.printStackTrace();
							} catch (WriteException e) {
								// TODO Auto-generated
								// catch block
								e.printStackTrace();
							}
							b++;

							if (gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getBranches() != null) {
								for (int l = 0; l < gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getArity(); l++) {
									String nameThird = gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getName();
									Label nodeThird = new Label(b, a, nameThird);
									try {
										geneContent.addCell(nodeThird);
									} catch (RowsExceededException e) {
										// TODO Auto-generated
										// catch block
										e.printStackTrace();
									} catch (WriteException e) {
										// TODO Auto-generated
										// catch block
										e.printStackTrace();
									}
									b++;

									if (gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getBranches() != null) {
										for (int m = 0; m < gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getArity(); m++) {
											String nameFourth = gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getName();
											Label nodeFouth = new Label(b, a, nameFourth);
											try {
												geneContent.addCell(nodeFouth);
											} catch (RowsExceededException e) {
												// TODO Auto-generated
												// catch block
												e.printStackTrace();
											} catch (WriteException e) {
												// TODO Auto-generated
												// catch block
												e.printStackTrace();
											}
											b++;

											if (gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getBranches() != null)
												for (int n = 0; n < gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getArity(); n++) {
													String nameFifth = gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getChild(n).getName();
													Label nodeFifth = new Label(b, a, nameFifth);
													try {
														geneContent.addCell(nodeFifth);
													} catch (RowsExceededException e) {
														// TODO Auto-generated
														// catch block
														e.printStackTrace();
													} catch (WriteException e) {
														// TODO Auto-generated
														// catch block
														e.printStackTrace();
													}
													b++;
												}
										}
									}
								}
							}
						}
					}
				}
			}

			try {

				geneContent.addCell(nodeRoot);
				geneContent.addCell(geneNumber);
				geneContent.addCell(nodeMaxDepth);
			} catch (RowsExceededException e) {
				// TODO Auto-generated
				// catch block
				e.printStackTrace();
			} catch (WriteException e) {
				// TODO Auto-generated
				// catch block
				e.printStackTrace();
			}

			a++;
		}

		Label geneNumber = new Label(0, 0, "Gene Number");
		Label geneMaxDepth = new Label(1, 0, "Gene MaxDepth");
		Label rootNode = new Label(2, 0, "Root Node");
		Label firstNode1 = new Label(3, 0, "FirstNode 1");
		Label firstNode2 = new Label(4, 0, "FirstNode 2");
		Label secondNode1 = new Label(5, 0, "Second Node 1");
		Label secondNode2 = new Label(6, 0, "Second Node 2");
		Label thirdNode1 = new Label(7, 0, "Third Node 1");
		Label thirdNode2 = new Label(8, 0, "Third Node 2");
		Label fourthNode1 = new Label(9, 0, "Fourth Node 1");
		Label fourthNode2 = new Label(10, 0, "Fourth Node 2");
		Label fifthNode1 = new Label(11, 0, "Fifth Node 1");
		Label fifthNode2 = new Label(12, 0, "Fifth Node 2");

		try {
			geneContent.addCell(geneNumber);
			geneContent.addCell(geneMaxDepth);
			geneContent.addCell(rootNode);
			geneContent.addCell(firstNode1);
			geneContent.addCell(firstNode2);
			geneContent.addCell(secondNode1);
			geneContent.addCell(secondNode2);
			geneContent.addCell(thirdNode1);
			geneContent.addCell(thirdNode2);
			geneContent.addCell(fourthNode1);
			geneContent.addCell(fourthNode2);
			geneContent.addCell(fifthNode1);
			geneContent.addCell(fifthNode2);

		} catch (RowsExceededException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (WriteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}// scheduleExport end

	public void scheduleExport(GeneManager gm) {

		int r = 1;

		for (int i = 0; i < gm.getBestGeneList().size(); i++)
		// Gene 갯수 체크
		{
			for (int j = 0; j < gm.getBestGeneList().get(i).scheduleList.size(); j++) {
				// Gene의 스케줄 갯수 체크
				for (int k = 0; k < gm.getBestGeneList().get(i).scheduleList.get(j).getMachineIndex().size(); k++)
				// 스케줄에 해당하는 머신 체크
				{
					for (int l = 0; l < gm.getBestGeneList().get(i).scheduleList.get(j).getMachineIndex().get(k).getMachineSchedule().size(); l++) {
						// 각 머신에 해당하는 잡 스케줄

						Number gene = new Number(0, r, i);
						// Gene Number

						Number schedule = new Number(1, r, j);
						// Schedule Number

						Number machine = new Number(2, r, gm.getBestGeneList().get(i).scheduleList.get(j).getMachineIndex().get(k).getIndex());
						// Machine

						Number selectedJob = new Number(3, r, gm.getBestGeneList().get(i).scheduleList.get(j).getMachineIndex().get(k).getMachineSchedule().get(l).getJobIndex());
						// Selected Job

						Number processingTime = new Number(4, r, gm.getBestGeneList().get(i).scheduleList.get(j).getMachineIndex().get(k).getMachineSchedule().get(l).getProcessingTime());
						// ProcessingTime

						Number scheduleCmax = new Number(5, r, gm.getBestGeneList().get(i).scheduleList.get(j).getMachineIndex().get(k).getTotalWorkingTime());
						// Schedule Cmax

						try {

							ltpSchedule.addCell(gene);
							ltpSchedule.addCell(schedule);
							ltpSchedule.addCell(machine);
							ltpSchedule.addCell(selectedJob);
							ltpSchedule.addCell(processingTime);
							ltpSchedule.addCell(scheduleCmax);

						} catch (RowsExceededException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (WriteException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

						r++;
					}
				}

			}

			Label gene = new Label(0, 0, "Gene");
			Label schedule = new Label(1, 0, "Schedule");
			Label machine = new Label(2, 0, "Machine");
			Label selectedJob = new Label(3, 0, "Selected Job");
			Label processingTime = new Label(4, 0, "Processing Time");
			Label scheduleCmax = new Label(5, 0, "Schedule Cmax");

			try {

				ltpSchedule.addCell(gene);
				ltpSchedule.addCell(schedule);
				ltpSchedule.addCell(machine);
				ltpSchedule.addCell(selectedJob);
				ltpSchedule.addCell(processingTime);
				ltpSchedule.addCell(scheduleCmax);

			} catch (RowsExceededException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (WriteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} // 첫번째 들어가는 포문 End

	}

}
